home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / mig / RCS / Mig_RequestIdleHosts.c,v < prev    next >
Text File  |  1990-09-24  |  15KB  |  583 lines

  1. head     2.4;
  2. branch   ;
  3. access   ;
  4. symbols  no-auto-remigrate:2.1 installed:2.0;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 2.4
  10. date     90.09.24.14.46.49;  author douglis;  state Exp;
  11. branches ;
  12. next     2.3;
  13.  
  14. 2.3
  15. date     90.08.15.15.59.17;  author douglis;  state Exp;
  16. branches ;
  17. next     2.2;
  18.  
  19. 2.2
  20. date     90.06.26.18.44.20;  author douglis;  state Exp;
  21. branches ;
  22. next     2.1;
  23.  
  24. 2.1
  25. date     90.06.22.14.58.26;  author douglis;  state Exp;
  26. branches ;
  27. next     2.0;
  28.  
  29. 2.0
  30. date     90.03.10.13.13.05;  author douglis;  state Stable;
  31. branches ;
  32. next     1.3;
  33.  
  34. 1.3
  35. date     90.03.10.13.11.34;  author douglis;  state Exp;
  36. branches ;
  37. next     1.2;
  38.  
  39. 1.2
  40. date     90.02.28.10.58.49;  author douglis;  state Exp;
  41. branches ;
  42. next     1.1;
  43.  
  44. 1.1
  45. date     90.02.16.14.29.46;  author douglis;  state Exp;
  46. branches ;
  47. next     ;
  48.  
  49.  
  50. desc
  51. @Source code for the Mig_RequestIdleHosts procedure.
  52. This procedure returns one or more idle hosts that may be
  53. used for migration with a specified priority.
  54. @
  55.  
  56.  
  57. 2.4
  58. log
  59. @added callback flag to MigHostCache to make it easier to flag all hosts as reclaimed after error
  60. @
  61. text
  62. @/* 
  63.  * Mig_RequestIdleHosts.c --
  64.  *
  65.  *    Source code for the Mig_RequestIdleHosts procedure.
  66.  *    This procedure returns one or more idle hosts that may be
  67.  *    used for migration with a specified priority.
  68.  *
  69.  * Copyright 1990 Regents of the University of California
  70.  * Permission to use, copy, modify, and distribute this
  71.  * software and its documentation for any purpose and without
  72.  * fee is hereby granted, provided that the above copyright
  73.  * notice appear in all copies.  The University of California
  74.  * makes no representations about the suitability of this
  75.  * software for any purpose.  It is provided "as is" without
  76.  * express or implied warranty.
  77.  */
  78.  
  79. #ifndef lint
  80. static char rcsid[] = "$Header: /sprite/src/lib/c/mig/RCS/Mig_RequestIdleHosts.c,v 2.3 90/08/15 15:59:17 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  81. #endif not lint
  82.  
  83.  
  84. #include <sprite.h>
  85. #include <mig.h>
  86. #include <host.h>
  87. #include <errno.h>
  88. #include <stdio.h>
  89. #include <status.h>
  90. #include "migInt.h"
  91.  
  92. extern int errno;
  93. extern char *strerror();
  94. extern char *malloc();
  95.  
  96. void (*migCallBackPtr)() = NULL;/* Procedure to call if idle hosts become
  97.                    available, or NULL. */
  98.  
  99. /*
  100.  * Define some state values to keep track of what we know about the
  101.  * global daemon.
  102.  *
  103.  * MIGD_OKAY    - we believe everything's okay.
  104.  * MIGD_WAITING    - waiting for the local migration daemon to talk to the global
  105.  *           daemon.
  106.  * MIGD_ERROR    - we've already hit an error and we don't want to announce 
  107.  *           further errors.
  108.  */
  109. typedef enum {
  110.     MIGD_OKAY,
  111.     MIGD_WAITING,
  112.     MIGD_ERROR,
  113. } MigdState;
  114.  
  115. /*
  116.  *----------------------------------------------------------------------
  117.  *
  118.  * StartMigd --
  119.  *
  120.  *    Fork a process to become the local migration daemon.
  121.  *
  122.  * Results:
  123.  *    0 for successful completion, -1 for error, in which case
  124.  *    errno indicates the nature of the error.  The parent
  125.  *    will return success as long as it can successfully fork.  That
  126.  *     doesn't necessarily mean the migration daemon has been started,
  127.  *    at least by the child, but the parent will go
  128.  *     ahead and try to contact the daemon again in any case.
  129.  *
  130.  * Side effects:
  131.  *    A new process is spawned and it tries to invoke migd.
  132.  *
  133.  *----------------------------------------------------------------------
  134.  */
  135.  
  136. static int
  137. StartMigd()
  138. {
  139.     int pid;
  140.     char *argArray[4];
  141.     
  142.     pid = fork();
  143.     if (pid < 0) {
  144.     fprintf(stderr, "couldn't fork\n");
  145.     return(-1);
  146.     }
  147.     if (pid > 0) {
  148.     /*
  149.      * We use the sprite Proc_Wait because we don't want to
  150.      * find out about any other children.
  151.      */
  152.     ReturnStatus status =
  153.         Proc_Wait(1, &pid, PROC_WAIT_BLOCK, (Proc_PID *) NULL,
  154.               (int *) NULL, (int *) NULL, (int *) NULL,
  155.               (Proc_ResUsage *) NULL);
  156.     if (status != SUCCESS) {
  157.         fprintf(stderr, "Error waiting for child to start migd: %s.",
  158.            Stat_GetMsg(status));
  159.         return(-1);
  160.     }
  161.     return(0);
  162.     }
  163.  
  164.     /*
  165.      * We are the child, and will try to become the migration daemon.
  166.      * First, sleep for just a moment so that we don't exit before our
  167.      * parent has waited for us... we don't want a user's signal handler to
  168.      * find out about us.  Then try to invoke migd.
  169.      */
  170.     sleep(1);
  171.     (void) system("/sprite/daemons/migd -D 2 -L");
  172.     exit(0);
  173. }
  174.  
  175.  
  176.  
  177.  
  178.  
  179. /*
  180.  *----------------------------------------------------------------------
  181.  *
  182.  * Mig_RequestIdleHosts --
  183.  *
  184.  *    Obtain one or more idle hosts from the migration server.
  185.  *    The caller specifies the number of hosts requested, the
  186.  *    priority at which they'll be used, flags to tell the daemon,
  187.  *    a callback procedure if a host is reclaimed or more hosts are
  188.  *    available, and an array to hold the identifiers of hosts.
  189.  *
  190.  * Results:
  191.  *    On error, -1 is returned, else the number of hosts in hostIDArray
  192.  *    is returned.  0 indicates no hosts were available.
  193.  *
  194.  * Side effects:
  195.  *      If the connection to the global server has not been opened, then
  196.  *    it is opened.  A callback is registered if one is specified.
  197.  *    If the local daemon isn't running, it is started.
  198.  *
  199.  *----------------------------------------------------------------------
  200.  */
  201. int
  202. Mig_RequestIdleHosts(numHosts, priority, flags, callBackPtr, hostArray)
  203.     int numHosts;        /* Number of hosts requested. */
  204.     int priority;        /* Priority of tasks; see mig.h */
  205.     int flags;            /* Flags for mig daemon; ditto. */
  206.     void (*callBackPtr)();    /* Procedure to call when getting
  207.                  * messages from mig daemon. */
  208.     int hostArray[];        /* Array of integers to fill with hostIDs. */
  209. {
  210.     Mig_IdleRequest request;
  211.     int virtualHost;
  212.     int physicalHost;
  213.     char *buffer;         /* Dynamically-allocated buffer for result
  214.                    of ioctl. */
  215.     unsigned int bufSize;    /* Size of buffer. */
  216.     int *intPtr;         /* Pointer into buffer. */
  217.     int i;            /* Counter. */
  218.     int status;            /* Status of system calls. */
  219.     int retries;        /* Count of retries if error during ioctl. */
  220.     int numWanted;        /* Number of hosts we wanted, set to
  221.                    numHosts. */
  222.     static MigdState migdState
  223.     = MIGD_OKAY;         /* We think migd is doing fine. */
  224.  
  225.  
  226. #ifdef DEBUG
  227.     fprintf(stderr, "Mig_RequestIdleHosts called.\n");
  228. #endif /* DEBUG */
  229.     if (mig_GlobalPdev < 0) {
  230.     if (MigOpenPdev(TRUE) < 0) {
  231. #ifdef DEBUG
  232.         fprintf(stderr, "Mig_RequestIdleHosts encountered error contacting global daemon.\n");
  233. #endif /* DEBUG */
  234.         return(-1);
  235.     }
  236.     }
  237.  
  238.  
  239.     if (!migGetNewHosts && !Mig_ConfirmIdle(0)) {
  240. #ifdef DEBUG
  241.     fprintf(stderr, "Mig_RequestIdleHosts -- no new hosts available.\n");
  242. #endif /* DEBUG */
  243.     return(0);
  244.     }
  245.     /*
  246.      * Tell the daemon what our physical host is so it doesn't try to tell
  247.      * us to migrate to this host.
  248.      */
  249.     status = Proc_GetHostIDs(&virtualHost, &physicalHost);
  250.     if (status != SUCCESS) {
  251.     errno = Compat_MapCode(status);
  252.     return(-1);
  253.     }
  254.  
  255.     request.numHosts = numHosts;
  256.     request.priority = priority;
  257.     request.flags = flags;
  258.     request.virtHost = virtualHost;
  259.  
  260.     bufSize = sizeof(int) * (1 + numHosts);
  261.     buffer = malloc(bufSize);
  262.     if (buffer == (char *) NULL) {
  263.     errno = ENOMEM;
  264.     return(-1);
  265.     }
  266.     for (retries = 2; retries >= 0; retries--) {
  267. #ifdef DEBUG
  268.     fprintf(stderr, "Mig_RequestIdleHosts starting ioctl.\n");
  269. #endif                /* DEBUG */
  270.     if (MigSetAlarm() < 0) {
  271.         fprintf(stderr,
  272.             "Error setting alarm for contact with migd.\n");
  273.         return(-1);
  274.     }
  275.     status = Fs_IOControl(mig_GlobalPdev, IOC_MIG_GETIDLE,
  276.                   sizeof(Mig_IdleRequest),
  277.                   (char *) &request,
  278.                   bufSize, buffer);
  279.     if (MigClearAlarm() < 0) {
  280.         fprintf(stderr,
  281.             "Error clearing alarm for contact with migd.\n");
  282.     }
  283. #ifdef DEBUG
  284.     fprintf(stderr, "Mig_RequestIdleHosts ioctl returned %x.\n", status);
  285. #endif                /* DEBUG */
  286.     if (status != SUCCESS) {
  287.         if (status == NET_NOT_CONNECTED) {
  288.         if (migdState == MIGD_OKAY) {
  289.             fprintf(stderr,
  290.                 "No migd daemon running on your host.  Waiting to see if it starts.\n");
  291.             migdState = MIGD_WAITING;
  292.             sleep(10);
  293.  
  294.         } else if (migdState == MIGD_WAITING) {
  295.             fprintf(stderr,
  296.                 "Starting a new migd.\n");
  297.             migdState = MIGD_ERROR;
  298.             if (StartMigd() < 0) {
  299.             return(0);
  300.             }
  301.             sleep(5);
  302.         }
  303.         }
  304.         close(mig_GlobalPdev);
  305.         mig_GlobalPdev = 0;
  306.         if (retries == 0 || MigOpenPdev(TRUE) < 0) {
  307.         if (migdState != MIGD_ERROR) {
  308.             fprintf(stderr,
  309.                 "Mig_RequestIdleHosts: error during ioctl to global master: %s\n",
  310.                 Stat_GetMsg(status));
  311.             migdState = MIGD_ERROR;
  312.         }
  313.         errno = Compat_MapCode(status);
  314.         free(buffer);
  315.         return(-1);
  316.         }
  317.     } else {
  318.         break;
  319.     }
  320.     }
  321.  
  322.     migdState == MIGD_OKAY;
  323.     intPtr = (int *) buffer;
  324.     numWanted = numHosts;
  325.     numHosts = *intPtr;
  326. #ifdef DEBUG_REQUEST
  327.     fprintf(stderr, "numHosts = %d\n", numHosts);
  328.     fflush(stderr);
  329. #endif /* DEBUG_REQUEST */
  330.  
  331.     intPtr++;
  332.  
  333.     for (i = 0; i < numHosts; i++) {
  334.     hostArray[i] = *intPtr;
  335.     (void) MigHostCache(*intPtr, MIG_CACHE_ADD, FALSE);
  336. #ifdef DEBUG
  337.     fprintf(stderr, "hostArray[%d] = %d\n", i, *intPtr);
  338.     fflush(stderr);
  339. #endif /* DEBUG */
  340.     intPtr++;
  341.     }
  342.  
  343.     free(buffer);
  344.     if (numHosts < numWanted) {
  345. #ifdef DEBUG
  346.     fprintf(stderr, "Mig_RequestIdleHosts didn't get enough hosts.\n");
  347. #endif /* DEBUG */
  348.     migGetNewHosts = 0;
  349.     }
  350.     if (callBackPtr != NULL) {
  351.     migCallBackPtr = callBackPtr;
  352.     }
  353. #ifdef DEBUG
  354.     fprintf(stderr, "Mig_RequestIdleHosts returning %d hosts.\n", numHosts);
  355. #endif /* DEBUG */
  356.     return(numHosts);
  357.     
  358. }
  359. @
  360.  
  361.  
  362. 2.3
  363. log
  364. @added logic to wait for local daemon to start if we're informed none exists.
  365. this avoids us starting a new one when the old one just hasn't talked to 
  366. the global daemon yet.
  367. @
  368. text
  369. @d19 1
  370. a19 1
  371. static char rcsid[] = "$Header: /sprite/src/lib/c/mig/RCS/Mig_RequestIdleHosts.c,v 2.2 90/06/26 18:44:20 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  372. d274 1
  373. a274 1
  374.     (void) MigHostCache(*intPtr, MIG_CACHE_ADD);
  375. @
  376.  
  377.  
  378. 2.2
  379. log
  380. @set the call back pointer regardless.
  381. before, it would only set it if not enough hosts were obtained.
  382. @
  383. text
  384. @d19 1
  385. a19 1
  386. static char rcsid[] = "$Header: /sprite/src/lib/c/mig/RCS/Mig_RequestIdleHosts.c,v 2.1 90/06/22 14:58:26 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  387. d38 15
  388. d107 1
  389. a107 2
  390.      * find out about us.  Then try to invoke migd, and then sleep a bit
  391.      * before returning to our parent so things can get set up.
  392. a110 1
  393.     sleep(5);
  394. d161 2
  395. a162 1
  396.     static int didMsg = 0;    /* Error message printed? */
  397. d205 1
  398. a205 2
  399.     for (retries = 2; retries >= 0; retries--) 
  400.     {
  401. d207 15
  402. a221 15
  403.         fprintf(stderr, "Mig_RequestIdleHosts starting ioctl.\n");
  404. #endif /* DEBUG */
  405.         if (MigSetAlarm() < 0) {
  406.         fprintf(stderr,
  407.             "Error setting alarm for contact with migd.\n");
  408.         return(-1);
  409.         }
  410.         status = Fs_IOControl(mig_GlobalPdev, IOC_MIG_GETIDLE,
  411.                   sizeof(Mig_IdleRequest),
  412.                   (char *) &request,
  413.                   bufSize, buffer);
  414.         if (MigClearAlarm() < 0) {
  415.         fprintf(stderr,
  416.             "Error clearing alarm for contact with migd.\n");
  417.         }
  418. d223 16
  419. a238 11
  420.         fprintf(stderr, "Mig_RequestIdleHosts ioctl returned %x.\n", status);
  421. #endif /* DEBUG */
  422.         if (status != SUCCESS) {
  423.         if (!didMsg) {
  424.             didMsg = 1;
  425.             if (status == NET_NOT_CONNECTED) {
  426.             fprintf(stderr,
  427.            "No migd daemon running on your host.  Will start one.\n");
  428.             if (StartMigd() < 0) {
  429.                 return(0);
  430.             }
  431. d240 1
  432. d242 9
  433. a250 12
  434.         close(mig_GlobalPdev);
  435.         mig_GlobalPdev = 0;
  436.         if (retries == 0 || MigOpenPdev(TRUE) < 0) {
  437.             if (!didMsg) {
  438.             fprintf(stderr,
  439.                    "Mig_RequestIdleHosts: error during ioctl to global master: %s\n",
  440.                    Stat_GetMsg(status));
  441.             didMsg = 1;
  442.             }
  443.             errno = Compat_MapCode(status);
  444.             free(buffer);
  445.             return(-1);
  446. d252 3
  447. a254 2
  448.         } else {
  449.         break;
  450. d256 2
  451. d259 1
  452. d261 1
  453. @
  454.  
  455.  
  456. 2.1
  457. log
  458. @changes for alarms for timeouts with migd and for printing to stderr instead of syslog
  459. @
  460. text
  461. @d19 1
  462. a19 1
  463. static char rcsid[] = "$Header: /sprite/src/lib/c/mig/RCS/Mig_RequestIdleHosts.c,v 2.0 90/03/10 13:13:05 douglis Stable Locker: douglis $ SPRITE (Berkeley)";
  464. d267 3
  465. a269 3
  466.     if (callBackPtr != NULL) {
  467.         migCallBackPtr = callBackPtr;
  468.     }
  469. @
  470.  
  471.  
  472. 2.0
  473. log
  474. @Changing version numbers.
  475. @
  476. text
  477. @d19 1
  478. a19 1
  479. static char rcsid[] = "$Header: /sprite/src/lib/c/mig/RCS/Mig_RequestIdleHosts.c,v 1.3 90/03/10 13:11:34 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  480. a24 1
  481. #include <syslog.h>
  482. d68 1
  483. a68 1
  484.     syslog(LOG_ERR, "couldn't fork\n");
  485. d81 1
  486. a81 1
  487.         syslog(LOG_ERR, "Error waiting for child to start migd: %s.",
  488. d152 1
  489. a152 1
  490.     syslog(LOG_INFO, "Mig_RequestIdleHosts called.\n");
  491. d157 1
  492. a157 1
  493.         syslog(LOG_INFO, "Mig_RequestIdleHosts encountered error contacting global daemon.\n");
  494. d166 1
  495. a166 1
  496.     syslog(LOG_INFO, "Mig_RequestIdleHosts -- no new hosts available.\n");
  497. d194 1
  498. a194 1
  499.         syslog(LOG_INFO, "Mig_RequestIdleHosts starting ioctl.\n");
  500. d196 5
  501. d205 4
  502. d210 1
  503. a210 1
  504.         syslog(LOG_INFO, "Mig_RequestIdleHosts ioctl returned %x.\n", status);
  505. d216 1
  506. a216 1
  507.             syslog(LOG_WARNING,
  508. d227 1
  509. a227 1
  510.             syslog(LOG_WARNING,
  511. d264 1
  512. a264 1
  513.     syslog(LOG_INFO, "Mig_RequestIdleHosts didn't get enough hosts.\n");
  514. d272 1
  515. a272 1
  516.     syslog(LOG_INFO, "Mig_RequestIdleHosts returning %d hosts.\n", numHosts);
  517. @
  518.  
  519.  
  520. 1.3
  521. log
  522. @fork off local daemon if none running.
  523. @
  524. text
  525. @d19 1
  526. a19 1
  527. static char rcsid[] = "$Header: /sprite/src/lib/c/mig/RCS/Mig_RequestIdleHosts.c,v 1.2 90/02/28 10:58:49 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  528. @
  529.  
  530.  
  531. 1.2
  532. log
  533. @added migCallBackPtr use.  changed Mig_OpenPdev to internal Mig routine.
  534. added debug msg if the daemon says no local daemon is running.
  535. @
  536. text
  537. @d19 1
  538. a19 1
  539. static char rcsid[] = "$Header: /sprite/src/lib/c/mig/RCS/Mig_RequestIdleHosts.c,v 1.1 90/02/16 14:29:46 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  540. d43 66
  541. d124 1
  542. d192 1
  543. a192 1
  544.     for (retries = 1; retries >= 0; retries--) 
  545. a207 3
  546.             syslog(LOG_WARNING, "No migd daemon running on your host.\n");
  547.             return(0);
  548.             } else {
  549. d209 4
  550. a212 2
  551.                    "Mig_RequestIdleHosts: error during ioctl to global master: %s\n",
  552.                    Stat_GetMsg(status));
  553. d218 6
  554. @
  555.  
  556.  
  557. 1.1
  558. log
  559. @Initial revision
  560. @
  561. text
  562. @d19 1
  563. a19 1
  564. static char rcsid[] = "$Header: /user2/douglis/pdev_mig/mig_p/RCS/Mig_RequestIdleHosts.c,v 1.3 90/02/13 10:07:19 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  565. d29 1
  566. d36 3
  567. a60 1
  568. /* ARGSUSED */
  569. d82 1
  570. d89 1
  571. a89 1
  572.     if (Mig_OpenPdev(TRUE) < 0) {
  573. d138 11
  574. a148 3
  575.         syslog(LOG_WARNING,
  576.                "Mig_RequestIdleHosts: error during ioctl to global master: %s\n",
  577.                Stat_GetMsg(status));
  578. d151 1
  579. a151 1
  580.         if (retries == 0 || Mig_OpenPdev(TRUE) < 0) {
  581. d187 3
  582. @
  583.